package com.yungu.swift.order.dao;

import com.github.miemiedev.mybatis.paginator.domain.PageBounds;
import com.github.miemiedev.mybatis.paginator.domain.PageList;
import com.yungu.swift.base.mapper.IMapper;
import com.yungu.swift.base.model.admin.AdminParam;
import com.yungu.swift.order.helper.model.DayOrderCountVo;
import com.yungu.swift.order.helper.model.DriverPrevOrderDiffVo;
import com.yungu.swift.order.model.dto.OrderDto;
import com.yungu.swift.order.model.param.AdminMapTodayOrderPageParam;
import com.yungu.swift.order.model.param.CrosstownOrderParam;
import com.yungu.swift.order.model.vo.AdminChildOrderInfoVo;
import com.yungu.swift.order.model.vo.AdminGeneralOrderVo;
import com.yungu.swift.order.model.vo.AdminJoinCountVo;
import com.yungu.swift.order.model.vo.AdminMainOrderDetailVo;
import com.yungu.swift.order.model.vo.AdminMainOrderInfoVo;
import com.yungu.swift.order.model.vo.AdminMapTodayOrderVo;
import com.yungu.swift.order.model.vo.AdminOrderInvoiceDetailVo;
import com.yungu.swift.order.model.vo.AdminOrderReturnVisitVo;
import com.yungu.swift.order.model.vo.AdminOrderTravelStatusVO;
import com.yungu.swift.order.model.vo.AllPassengerOrderVo;
import com.yungu.swift.order.model.vo.ApiCrosstownOrderInfoVo;
import com.yungu.swift.order.model.vo.ApiDriverOrderVo;
import com.yungu.swift.order.model.vo.ApiOrderInfoVo;
import com.yungu.swift.order.model.vo.CrosstownHomeOrderInfoVo;
import com.yungu.swift.order.model.vo.CrosstownMergeAssignInfoVo;
import com.yungu.swift.order.model.vo.CrosstownOrderAssignVo;
import com.yungu.swift.order.model.vo.CrosstownOrderDetailVo;
import com.yungu.swift.order.model.vo.CrosstownOrderPoolInfoVo;
import com.yungu.swift.order.model.vo.CrosstownOrderTaskInfoVo;
import com.yungu.swift.order.model.vo.CrosstownOrderVo;
import com.yungu.swift.order.model.vo.CrosstownWaitStartOrderVo;
import com.yungu.swift.order.model.vo.JoinOrderAssignVo;
import com.yungu.swift.order.model.vo.JsonOrderDetailVo;
import com.yungu.swift.order.model.vo.JsonOrderListVo;
import com.yungu.swift.order.model.vo.OrderItemVo;
import com.yungu.swift.order.model.vo.TripSharingInfoVo;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;

import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * Copyright © 厦门云谷互联信息科技有限公司 2018-2020 All Right Reserved
 * <p>
 * 订单Mapper
 *
 * @author Zerrion
 * @version 1.0.0-RELEASE
 * @since 2018-07-03 15:24
 */
public interface OrderMapper extends IMapper<OrderDto> {


    List<JsonOrderDetailVo> listOrderDetail(Map<String, Object> params);

    /**
     * 获取已经完成的订单（没人接单的不计算在内）
     *
     * @param paramMap   Map
     * @param pageBounds PageBounds
     * @return List<JsonOrderListVo>
     */
    List<JsonOrderListVo> queryOrderDone(Map<String, Object> paramMap, PageBounds pageBounds);

    /**
     * queryOrderDoing
     *
     * @param paramMap Map
     * @return List<JsonOrderListVo>
     */
    List<JsonOrderListVo> queryOrderDoing(Map<String, Object> paramMap);

    /**
     * getAllByStatus
     *
     * @param doingMap Map
     * @return List<JsonOrderListVo>
     */
    List<JsonOrderListVo> getAllByStatus(Map<String, Object> doingMap);

    /**
     * getCount
     *
     * @param params Map
     * @return Integer
     */
    Integer getCount(Map<String, Object> params);

    /**
     * 根据订单状态和查询时间获取订单总数
     *
     * @param map Map
     * @return Integer
     */
    Integer findOrderCountByStatus(Map<String, Object> map);

    /**
     * 根据实际接单司机actualDriverUuid字段查询订单列表，按出发时间降续排列
     *
     * @param map        Map
     * @param pageBounds PageBounds
     * @return PageList<JsonOrderListVo>
     */
    PageList<JsonOrderListVo> queryPageList(Map<String, Object> map, PageBounds pageBounds);


    /**
     * 获取司机已完成的订单
     */
    List<OrderDto> driverAccomplishOrder(@Param("actualDriverUuid") String actualDriverUuid);

    /**
     * 获取司机当天已完成的订单数
     *
     * @param map Map
     * @return Integer
     */
    Integer queryTodayOrderDone4Driver(Map<String, Object> map);

    /**
     * 当天订单数统计
     *
     * @param list
     * @return
     */
    List<DayOrderCountVo> listDayOrderCount(List<String> list);


    /**
     * 跨车：乘客获取进行中的订单
     *
     * @param map Map
     * @return List<OrderDto>
     */
    List<OrderDto> findPasDoingOrder(Map<String, Object> map);


    /**
     * 跨车：司机订单下有效的乘客订单(不包括已取消的订单)
     *
     * @param map Map
     * @return List<OrderDto>
     */
    List<OrderDto> findValidList(Map<String, Object> map);

    /**
     * 后台获取 乘客/司机 的订单列表
     *
     * @param map        Map
     * @param pageBounds PageBounds
     * @return PageList<JsonOrderListVo>
     */
    PageList<JsonOrderListVo> findOrderList(Map<String, Object> map, PageBounds pageBounds);


    /**
     * 获取用车时间在半小时以内的最新一个预约订单
     *
     * @param map Map
     * @return JsonOrderListVo
     */
    JsonOrderListVo queryAppointOrderIn30Minute(Map<String, Object> map);

    /**
     * 跨车拼车：获取司机未完成的订单
     *
     * @param map Map
     * @return List<OrderDto>
     */
    List<OrderDto> findDriDoing(Map<String, Object> map);

    /**
     * 跨车拼车：获取司机未完成的预约订单
     *
     * @param map Map
     * @return List<OrderDto>
     */
    List<OrderDto> findDriDoingAppoint(Map<String, Object> map);

    /**
     * 后台-订单处理中心-专车/快车/出租车订单-获取列表
     *
     * @param map        Map
     * @param pageBounds PageBounds
     * @return PageList<String> 司机的 uuid 集合
     */
    PageList<String> queryPageCommon(Map<String, Object> map, PageBounds pageBounds);

    /**
     * 后台-订单处理中心-专车/快车/出租车订单-订单导出
     *
     * @param params Map
     * @return List<GeneralOrderVo>
     */
    List<AdminGeneralOrderVo> exportCommon(Map<String, Object> params);

    /**
     * 后台-订单处理中心-专车/快车/出租车订单-获取列表 —— 数据补充
     *
     * @param map Map
     * @return Map
     */
    List<AdminGeneralOrderVo> fetchJoinDataByUuid(Map<String, Object> map);

    /**
     * 后台-订单处理中心-出租车订单-获取列表数量
     *
     * @param map Map
     * @return Integer
     */
    Integer countOrder(Map<String, Object> map);

    /**
     * 后台-订单处理中心-出租车订单-获取列表 —— 数据补充
     *
     * @param map Map
     * @return List<GeneralOrderVo>
     */
    List<AdminGeneralOrderVo> fetchJoinData(Map<String, Object> map);

    /**
     * 查看是否有效订单
     *
     * @param map Map
     * @return int
     */
    int isValidOrder(Map map);

    /**
     * 【后台】乘客按行程开票订单列表
     *
     * @param orderIds   orderUuid 列表
     * @param pageBounds PageBounds
     * @return PageList<OrderInvoiceDetailVo>
     */
    PageList<AdminOrderInvoiceDetailVo> orderInvoicePage(@Param("orderIds") Collection<String> orderIds, PageBounds pageBounds);

    /**
     * 初始化订单（后台系统改派）
     *
     * @param dto OrderDto
     * @return int
     */
    int init(OrderDto dto);

    /**
     * 跨车拼车：获取司机未完成的订单
     *
     * @return List<OrderDto>
     */
    List<OrderDto> get1HoursOrder();

    /**
     * 判断该司机手上是否有即时单
     *
     * @param driverUuid String
     * @return List<OrderDto>
     */
    List<OrderDto> driverHasRealTimeOrder(String driverUuid);

    /**
     * 获取司机所有未出发预约单
     *
     * @param params Map
     * @return List<JsonOrderListVo>
     */
    List<JsonOrderListVo> getAppointmentList(Map<String, Object> params);

    /**
     * 获取司机所有可抢预约单
     *
     * @param params Map
     * @return List<JsonOrderListVo>
     */
    List<JsonOrderListVo> getFreshAppointmentDetail(Map<String, Object> params);

    /**
     * orderTodayList
     *
     * @param todayOrderParam 今日订单参数
     * @param pageBounds      分页信息
     * @return PageList<OrderTodayListVo>
     */
    PageList<AdminMapTodayOrderVo> orderTodayList(AdminMapTodayOrderPageParam todayOrderParam, PageBounds pageBounds);

    /**
     * getOrderTodayList
     *
     * @param orderUuid 订单 uuid
     * @returnAdminMapTodayOrderVo
     */
    AdminMapTodayOrderVo orderTodayList(@Param("orderUuid") String orderUuid);

    /**
     * 判断该司机手上是否有进行中即时单、预约单和前后一小时预约
     *
     * @param params Map
     * @return List<OrderDto>
     */
    List<OrderDto> driverHasGoingOrder(Map<String, Object> params);

    /**
     * 根据司机id查到上一个订单号
     *
     * @param driverUuid
     * @return
     */
    String getTodayPrevOrderUuid(String driverUuid);

    /**
     * 司机距离上一单订单时间间隔
     *
     * @param list
     * @return
     */
    List<DriverPrevOrderDiffVo> listPreviousOrderDiff(List<String> list);

    /**
     * 获取乘客最近三次叫车成功并取消的订单
     *
     * @param params MapMap
     * @return List<OrderDto>
     */
    List<OrderDto> getLastCancelOrderByPassengerDistributed(Map<String, Object> params);

    /**
     * 获取司机进行中的订单
     *
     * @param params
     * @return
     */
    List<OrderDto> queryDriDoingOrder(Map<String, Object> params);

    /**
     * 获取3天内有取消订单的乘客的所有订单
     * （待定：根据乘客和创建时间倒序）
     *
     * @return
     */
    List<OrderDto> getCancelPassengerOrder();

    /**
     * 获取首页是否有进行中的订单
     *
     * @param params 参数集合
     * @return OrderDto
     * @author Zerrion
     * @date 2018/1/14
     */
    OrderDto getHomeOrderStatus(Map<String, Object> params);

    /**
     * 获取分页订单列表
     *
     * @param params     参数集合
     * @param pageBounds 分页对象
     * @return OrderDto
     * @author Zerrion
     * @date 2018/1/14
     */
    List<OrderItemVo> listOrder(Map<String, Object> params, PageBounds pageBounds);


    /**
     * getCompleteOrderByDate
     *
     * @param params Map
     * @return List<OrderDto>
     */
    List<OrderDto> getCompleteOrderByDate(Map<String, Object> params);

    /**
     * 拼车未完成订单数量
     *
     * @param params
     * @return
     */
    int countJoinUnCompleted(Map params);

    /**
     * 主子订单对象相关订单字段查询
     *
     * @param uuid
     * @return
     */
    OrderDto selectForMainChild(String uuid);

    /**
     * 获取主&子关联订单UUID
     *
     * @param uuid
     * @return
     */
    List<String> getRelatedUuids(String uuid);

    /**
     * 查询主订单匹配的子订单
     *
     * @return
     */
    List<OrderDto> findValidChildren(Map params);

    /**
     * 根据订单UUID查询所有关联拼车订单
     *
     * @return
     */
    List<OrderDto> findRelatedByOrderUuid(Map params);

    /**
     * 关联更新拼车订单状态
     *
     * @param orderUuid
     * @return
     */
    @Update("UPDATE t_order SET join_status=#{joinStatus}, update_on=NOW() WHERE (uuid=#{orderUuid} or main_order_uuid=#{orderUuid}) AND close_status=0 AND type_module in(3,5)")
    int updateStatusByJoinOrderRelatedUuid(@Param("orderUuid") String orderUuid, @Param("joinStatus") Integer joinStatus);

    /**
     * 关闭关联拼车订单
     *
     * @param orderUuid
     * @return
     */
    @Update("UPDATE t_order SET close_status=#{closeStatus}, update_on=NOW() WHERE (uuid=#{orderUuid} or main_order_uuid=#{orderUuid}) AND close_status=0 AND type_module=3")
    int closeStatusByJoinOrderRelatedUuid(@Param("orderUuid") String orderUuid, @Param("closeStatus") Integer closeStatus);

    /**
     * 查询司机跨城拼车子订单
     *
     * @param params
     * @param pageBounds
     * @return
     */
    PageList<JsonOrderDetailVo> joinPageList(Map<String, Object> params, PageBounds pageBounds);

    PageList<JoinOrderAssignVo> queryByAssign(Map<String, Object> params, PageBounds pageBounds);

    PageList<JoinOrderAssignVo> queryByAssignAll(Map<String, Object> params, PageBounds pageBounds);

    /**
     * 获取匹配有效拼车主订单
     *
     * @param params
     * @return
     */
    OrderDto findValidMatchJoinMainOrder(Map<String, Object> params);

    @Update("UPDATE t_order SET join_status=#{joinStatus}, update_on=NOW() WHERE uuid=#{orderUuid} AND close_status=0")
    int updateChildJoinOrderStatus(@Param("orderUuid") String orderUuid, @Param("joinStatus") Integer joinStatus);


    List<JsonOrderDetailVo> queryJoinByStatusTime(Map<String, Object> params);

    List<JsonOrderDetailVo> queryJoinByDeparOrder(Map<String, Object> params);

    /**
     * 根据 订单UUID 查询 某司机 未完成 拼车 订单
     *
     * @param targetDriverUuid
     * @param targetMainOrderUuid
     * @return
     */
    @Select("select count(0) from t_order where actual_driver_uuid=#{targetDriverUuid} and uuid!=#{targetMainOrderUuid} and type_module=3 and join_status<600 and close_status=0")
    int findExistedByUnCompleteJoinExcludeSelf(String targetDriverUuid, String targetMainOrderUuid);

    /**
     * 根据条件查询司机未完成订单
     *
     * @param m
     * @return
     */
    List<OrderDto> findByUnCompleteJoinOrder(Map m);

    List<Date> findSubDeparTime(@Param("mainOrderUuid") String mainOrderUuid);


    AdminJoinCountVo countJoinOrder(AdminParam adminParam);

    /**
     * 查询前一天并且创建时间距离超过30分钟，未派到单的订单（100）不包含拼车业务
     */
    List<OrderDto> getOverTimeExceptionList();

    /**
     * 行程分享
     *
     * @param orderUuid
     * @return
     */
    TripSharingInfoVo selectTripSharingInfo(String orderUuid);

    /**
     * 获取跨城小件收件码
     *
     * @return
     */
    List<JsonOrderDetailVo> getReceiptCode(Map<String, Object> params);

    /**
     * 获取未指派司机的拼车与小件订单
     */
    PageList<AdminChildOrderInfoVo> notAssignJoinOrderPage(Map<String, Object> param, PageBounds pageBounds);

    /**
     * 获取已指派司机的拼车与小件订单
     */
    PageList<AdminMainOrderInfoVo> yetAssignJoinOrderPage(Map<String, Object> param, PageBounds pageBounds);

    /**
     * 获取已指派司机的拼车与小件订单
     */
    List<AdminMainOrderInfoVo> exportYetAssignJoinOrder(Map<String, Object> param);

    /**
     * 通过订单ID获取子订单信息
     */
    List<AdminChildOrderInfoVo> getChildOrderInfoById(Map<String, Object> param);

    /**
     * 跨城订单处理顺序更新
     *
     * @param paramList
     * @return
     */
    int orderSequenceChange(@Param(value = "orderList") List<CrosstownOrderParam> paramList);

    /**
     * 跨城订单集合获取
     */
    PageList<CrosstownOrderVo> crosstownOrderListInfo(Map<String, Object> param, PageBounds pageBounds);

    /**
     * 获取拼友订单信息
     */
    List<AllPassengerOrderVo> allPassengerOrderInfo(Map<String, Object> param);

    /**
     * 跨城司机获取主单下的所有订单详情
     */
    List<CrosstownOrderDetailVo> crosstownOrderListDetail(Map<String, Object> param);

    /**
     * 校验乘客是否都已经上车或者都已经到达目的地
     *
     * @param param
     * @return
     */
    int verifyCrosstownOrderStatus(Map<String, Object> param);

    /**
     * 获取待出发订单
     */
    List<CrosstownOrderAssignVo> getWaitStartOrder(Map<String, Object> param);

    /**
     * 获取跨城订单池
     */
    PageList<CrosstownOrderPoolInfoVo> getCrosstownOrderPoolInfo(Map<String, Object> param, PageBounds pageBounds);

    /**
     * 获取跨城订单池
     */
    Integer getCrosstownOrderPoolCount(Map<String, Object> param);

    /**
     * 获取司机待出发订单
     */
    List<CrosstownWaitStartOrderVo> getDriverWaitStartOrder(Map<String, Object> param);

    /**
     * 合并派单获取待出发订单
     *
     * @param params
     * @param pageBounds
     * @return
     */
    PageList<JoinOrderAssignVo> mergeAssignOrderQuery(Map<String, Object> params, PageBounds pageBounds);

    /**
     * 获取退款订单列表
     *
     * @param params
     * @return
     */
    List<OrderDto> queryRefundList(Map<String, Object> params);

    /**
     * 校验乘客是否是首单
     *
     * @return
     */
    @Select("select count(0) from t_order where passenger_uuid=#{passengerUuid} and uuid!=#{orderUuid} and type_module in(3,5) and join_status>500 and close_status=0")
    int checkPassengerFirstOrder(@Param("passengerUuid") String passengerUuid, @Param("orderUuid") String orderUuid);

    /**
     * 首单回访信息查询
     *
     * @return
     */
    PageList<AdminOrderReturnVisitVo> queryFirstOrderInfo(Map<String, Object> params, PageBounds pageBounds);

    /**
     * 跨城合并派单弹窗信息拉取
     *
     * @return
     */
    List<CrosstownMergeAssignInfoVo> crosstownMergeAssignInfo(@Param(value = "orderUuidList") List<String> params);

    /**
     * 获取跨城订单详情
     *
     * @return
     */
    ApiCrosstownOrderInfoVo getCrosstownOrderInfo(@Param(value = "orderUuid") String orderUuid);

    /**
     * 获取专快出租订单详情
     *
     * @return
     */
    ApiOrderInfoVo getOrderInfo(@Param(value = "orderUuid") String orderUuid);

    /**
     * 获取跨城进行中订单
     */
    @Select("select uuid from t_order where join_status in (410,500) and close_status = 0 and actual_driver_uuid = #{driverUuid} and type_main = 1")
    String getCrosstownUnderwayOrder(@Param(value = "driverUuid") String driverUuid);

    /**
     * 自动关闭跨城订单
     */
    @Update("update t_order close_status = 1,close_type= 'TIME_OUT',close_reason ='超时系统自动关闭' where FIND_IN_SET(uuid,#{orderUuids}) and close_status = 0 ")
    int autoCloseCrosstownOrder(@Param(value = "orderUuids") String orderUuids);

    /**
     * 获取跨城首页订单
     */
    List<CrosstownHomeOrderInfoVo> getCrosstownHomeOrderInfo(Map<String, Object> paraMap);

    /**
     * 跨城跨城校验是否有扫码下单未支付订单
     *
     * @return
     */
    @Select("select count(0) from t_order t where t.main_order_uuid = #{mainOrderUuid} and t.close_status = 0 and t.join_status = 100 ")
    int checkScanCodeOrderNoPay(@Param(value = "mainOrderUuid") String mainOrderUuid);


    /**
     * 获取未评价订单
     *
     * @return
     */
    @Select("select * from t_order t where t.passenger_uuid = #{passengerUuid} and ((t.type_module in (3,5) and t.type_main = 2 and t.close_status = 0 and t.join_status >=600)\n" +
            " or (t.type_module not in (3,5) and t.main_status = 4 and t.sub_status >=600)) order by t.create_on desc limit 1")
    OrderDto getNoEvaluationOrder(@Param(value = "passengerUuid") String passengerUuid);

    /**
     * 跨城主订单详情
     *
     * @return
     */
    AdminMainOrderDetailVo mainOrderDetail(@Param(value = "mainOrderUuid") String mainOrderUuid);

    /**
     * 跨城订单时间轴
     *
     * @return
     */
    List<AdminOrderTravelStatusVO> orderTravelStatus(@Param(value = "mainOrderUuid") String mainOrderUuid);

    /**
     * 统计司机订单数据
     *
     * @param driUuid
     * @param type
     * @param startDate
     * @param endDate
     * @return
     */
    ApiDriverOrderVo statisticDriverOrder(@Param("driUuid") String driUuid, @Param("type") Integer type,
                                          @Param("startDate") Date startDate, @Param("endDate") Date endDate);

    /**
     * 解绑跨城订单
     *
     * @param orderUuid
     * @return
     */
    @Update("UPDATE t_order SET main_order_uuid=null,actual_driver_uuid = null,join_status = 300 where uuid = #{orderUuid}")
    int reBindMainOrder(@Param("orderUuid") String orderUuid);

    /**
     * 跨城是否还存在子单
     *
     * @param mainOrderUuid
     * @return
     */
    @Select("select count(1) from t_order where main_order_uuid = #{mainOrderUuid} and close_status = 0 ")
    int existChildOrder(@Param("mainOrderUuid") String mainOrderUuid);

    /**
     * 关闭拼车主单
     *
     * @param mainOrderUuid
     * @return
     */
    @Update("UPDATE t_order SET close_status=1, update_on=NOW() WHERE uuid=#{mainOrderUuid}")
    int closeMainOrder(@Param("mainOrderUuid") String mainOrderUuid);


    /**
     * 跨城拼车行程任务列表
     *
     * @return
     */
    List<CrosstownOrderTaskInfoVo> taskList(@Param("mainOrderUuid") String mainOrderUuid);

    /**
     * 保存司机选择模式
     *
     * @return
     */
    @Update("update t_order set task_model = #{taskModel} where uuid=#{mainOrderUuid} ")
    int saveTaskModel(@Param("mainOrderUuid") String mainOrderUuid, @Param("taskModel") Integer taskModel);
}

